package com.example.demo.com.java8.stream;

import com.example.demo.com.java8.lambda.Apple;
import org.junit.Test;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.*;

/**
 * 终止操作
 * @author chengfei5
 * @date 2018/8/21
 */
public class TestStream3 {
    private List<Apple> appleList = Arrays.asList(
            new Apple(155,"green"),
            new Apple(156,"red"),
            new Apple(120,"green"),
            new Apple(159,"green"),
            new Apple(160,"red"),
            new Apple(110,"yellow"),
            new Apple(170,"red"),
            new Apple(180,"green")
    );
    /**
     * allMatch--检查是否匹配所有元素
     */
    @Test
    public void test1(){
        boolean b1 = appleList.stream().allMatch(e->"green".equals(e.getColor()));
        System.out.println(b1);
    }
    /**
     * anyMatch--检查至少匹配一个元素
     */
    @Test
    public void test2(){
        boolean b = appleList.stream()
                .anyMatch(e->"green".equals(e.getColor()));
        System.out.println(b);
    }

    /**
     * noneMatch
     */
    @Test
    public void test3(){
        boolean b = appleList.stream()
                .noneMatch(e->"green".equals(e.getColor()));
        System.out.println(b);
    }
    /**
     * findFirst : 获取第一个满足条件的元素
     */
    @Test
    public void test4(){
        Optional<Apple> apple1 = appleList.stream()
                .filter(apple -> apple.getWeight()>150)
                .findFirst();
        System.out.println(apple1);
    }

    /**
     * findAny：返回任意一个满足条件的元素
     */
    @Test
    public void test5(){
        Optional<Apple> apple1 = appleList.stream()
                .filter(apple -> apple.getWeight()>150)
                .findAny();
        System.out.println(apple1);
    }
    @Test
    public void test6(){
        /**
         * count :统计
         */
        long count = appleList.stream().count();
        System.out.println(count);
        appleList.stream().mapToInt(Apple::getWeight).sum();
        /**
         * max:获取最大的
         */
        Optional<Apple> max = appleList.stream().max(comparing(Apple::getWeight));
        System.out.println(max.get());
        /**
         * min:获取最大的
         */
        Optional<Apple> min = appleList.stream().min(comparing(Apple::getWeight));
        System.out.println(min.get());

    }
    /**
     * reduce:规约 可以将流中的元素反复结合起来，得到一个值
     */
    @Test
    public void test7(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        /**
         *
         * 1.首先有个起始值，0作为x
         * 2.从流中取出一个元素作为y
         * 3.执行lambda表达式
         */
        Integer sum = list.parallelStream()
                .reduce(0, (x, y) -> x + y);
        System.out.println(sum);

        /**
         * map-reduce操作
         */
        Optional<Integer> sumWeight = appleList.stream()
//  可行吗？              .reduce(0,(x,y)->x.getWeight()+y.getWeight())
                .map(Apple::getWeight)
                .reduce(Integer::sum);

        System.out.println(sumWeight.get());

    }

    /**
     * 收集：
     * collect
     */
    @Test
    public void test8(){
        List<Integer> weightList = appleList.stream()
                .map(Apple::getWeight)
                .collect(Collectors.toList());

        //常用应用场景，将多条sql语句拆分时，通常需要将一个集合的数据的外键提取，然后在查另一张表

        Set<String> stringSet = appleList.stream()
                .map(Apple::getColor)
                .collect(toSet());
        System.out.println(stringSet);

        //常用场景，list转map
        Map<Integer, Apple> collect = appleList.stream().collect(toMap(Apple::getWeight, Function.identity()));

        System.out.println(collect);
    }

    @Test
    public void test9(){
        /**
         * 总数
         */
        Long collect = appleList.stream()
                .collect(counting());
        System.out.println(collect);
        System.out.println("---------------------");
        /**
         * 平局值
         */
        Double collect1 = appleList.stream()
                .collect(averagingDouble(Apple::getWeight));
        System.out.println(collect1);
        System.out.println("---------------------");

        /**
         * 重量总和
         */
        Integer collect2 = appleList.stream()
                .collect(Collectors.summingInt(Apple::getWeight));
        System.out.println(collect2);
        System.out.println("---------------------");

        /**
         * 重量最大
         */
        Optional<Apple> max = appleList.stream()
//                .max(comparing(Apple::getWeight));
                .collect(Collectors.maxBy(comparing(Apple::getWeight)));
        /**重量最小
         * */
        appleList.stream()
                .collect(Collectors.minBy(comparing(Apple::getWeight)));
        /**
         * 分组分区
         */
        Map<String, List<Apple>> collect3 = appleList.stream()
                .collect(groupingBy(Apple::getColor));
        System.out.println(collect3);
        System.out.println("---------------------");

        Map<Boolean, List<Apple>> collect4 = appleList.stream()
                .collect(partitioningBy(e -> e.getWeight() > 150));
        System.out.println(collect4);
        System.out.println("---------------------");

        /**
         * 统计最大最小平均总和
         */
        IntSummaryStatistics collect5 = appleList.stream()
                .collect(summarizingInt(Apple::getWeight));
        System.out.println("苹果平均重量："+collect5.getAverage());
        System.out.println("苹果总个数："+collect5.getCount());
        System.out.println("苹果最大重量："+collect5.getMax());
        System.out.println("苹果最小重量："+collect5.getMin());
        System.out.println("苹果总量总和："+collect5.getSum());

        /**
         * 连接字符串
         */
        String collect6 = appleList.stream()
                .map(Apple::getColor)
                .collect(joining(","));
        System.out.println(collect6);
    }
    @Test
    public void test10(){
        List<String> stringList = Arrays.asList("aa","bb","aa");
        System.out.println(stringList.stream().distinct().collect(toList()));
    }

}
